#ifndef _COMPILATION_TASK_HANDLER_H_
#define _COMPILATION_TASK_HANDLER_H_

#include <compilation/instruction/Instruction.h>
#include <compilation/instruction/Expression.h>
#include <compilation/task/Task.h>


// InstructionHandler.
namespace compilation
{

template <InstructionType _Type, typename _TaskType, typename _AgendaType>
struct InstructionHandler
{
  typedef InstructionHandler base_handler;

  void operator ()(
      VirtualInstruction* instr,
      _TaskType& task,
      _AgendaType& continuations,
      WorkListReusability& reuse)
  {
    task.applyOn(*instr, continuations);
    continuations.markInstructionWith(task.getInstruction(), task);
    continuations.propagateOnUnmarked(instr, task, continuations, reuse);
  }
};

template <typename _TaskType, typename _AgendaType>
struct DefaultInstructionHandler
{
  template <InstructionType _Type>
  struct type : public InstructionHandler<_Type, _TaskType, _AgendaType> {};
};

} // compilation

// ExpressionHandler.
namespace compilation
{

template <ExpressionType _Type, typename _TaskType, typename _AgendaType>
struct ExpressionHandler
{
  typedef ExpressionHandler base_handler;

  void operator ()(
      VirtualExpression* instr,
      _TaskType& task,
      _AgendaType& continuations,
      WorkListReusability& reuse)
  { }
};

template <typename _TaskType, typename _AgendaType>
struct DefaultExpressionHandler
{
  template <ExpressionType _Type>
  struct type : public ExpressionHandler<_Type, _TaskType, _AgendaType> {};
};

} // compilation

#endif // _COMPILATION_TASK_HANDLER_H_
